
package _08等待唤醒机制;

import java.util.LinkedList;
import java.util.Queue;

public class TestDemo {

	public static void main(String[] args) throws InterruptedException {

		// 生产者 消费者

// 小明妈妈 做包子 	生产者		notify()
// 小明         吃包子     消费者		wait()
// 锅

		Pot pot = new Pot();

		// 小明
		Customer c = new Customer();
		Thread t2 = new Thread(c);
		t2.setName("小明");
		c.pot = pot;
		t2.start();

		// 小明妈妈
		Productor p = new Productor();
		Thread t1 = new Thread(p);
		t1.setName("小明妈妈");
		p.pot = pot;
		t1.start();

	}

}

// 锅
class Pot {
	public Queue<Integer> queue = new LinkedList<>();
	public int maxSize = 10;
	public int n;
}

// 生产者
class Productor implements Runnable {
	Pot pot;

	@Override
	public void run() {

		while (true) {
			synchronized (pot) {

				// 锅还没有满，不断做包子放入
				if (pot.queue.size() < pot.maxSize) {
					// 做包子
					pot.n++;
					// 放到锅里
					pot.queue.add(pot.n);
					System.out.println(Thread.currentThread().getName() + "做包子" + pot.n);
				} else {
					// 锅满了，发通知，告诉小明来吃包子
					System.out.println(Thread.currentThread().getName() + ":包子做好了,快来吃");
					// 唤醒正处于等待状态的线程
					pot.notify();

					System.out.println(Thread.currentThread().getName() + "休息一会儿");
					try {
						pot.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				}
			}

			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
	}
}

class Customer implements Runnable {
	Pot pot;

	@Override
	public void run() {
		while (true) {

			synchronized (pot) {

				if (pot.queue.size() > 0) {
					// 锅里有包子，吃包子
					int n = pot.queue.remove();
					System.out.println(Thread.currentThread().getName() + ":吃包子" + n);
				} else {
					// 锅里没包子，通知妈妈来做包子
					System.out.println(Thread.currentThread().getName() + "锅里是空的,妈妈来做包子把!等妈妈做包子");
					// 唤醒正处于等待状态的线程
					pot.notify();

					// 等待妈妈做完包子来通知
					try {
						pot.wait();
						System.out.println(Thread.currentThread().getName() + "来了，我来吃包子了");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}

			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}